# -*- coding: utf-8 -*-
# 如果你的程序（包括注释）中包含中文，请加上上面这一行，用于指明编码（utf-8）。
# #号开头的行都是注释。

# 如何编辑本程序：
#     用任何文本编辑器均可编辑。

# 如何运行本程序：
#     在终端中，运行：python p501_class.py
#

# 定义Dog类，类名一般首字母大写。
class Dog:
    # 类中的函数成为方法。
    
    # 特殊方法，构造实例的时候Python自动调用。
    def __init__(self, name, age):
        '''初始化属性。'''
        self.name = name
        self.age = age
        
    def sit(self):
        '''模拟小狗坐下。'''
        print(self.name.title() + ' is now sitting.')
        
    def roll_over(self):
        '''模拟小狗打滚。'''
        print(self.name.title() + ' rolled over.')
        
# 构造一个实例。
my_dog = Dog('willie', 6)  # Python会自动调用Dog.__init__()，self参数不用传递。

# 访问实例的属性。
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog is " + str(my_dog.age) + " years old.")

# 调用方法。
my_dog.sit()
my_dog.roll_over()

print()
print()

########################################
# Another class.

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
        
    def get_descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
        
    def read_odometer(self):
        print('This car has ' + str(self.odometer_reading) + ' miles.')
        
    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
            
    def increment_odometer(self, miles):
        self.odometer_reading += miles

        
my_car = Car('audi', 'a4', 2016)
print(my_car.get_descriptive_name())

my_car.odometer_reading = 1000
my_car.read_odometer()
my_car.update_odometer(2000)
my_car.read_odometer()

# 注：可以直接访问实例的属性，也可以通过调用方法实现属性的读写。
# 但应尽量采取后者的方式，以实现对象的封装（encapsulation）。


########################################
# Another class, with 'private' attributes.

class Person:
    # 类中的函数成为方法。
    
    # 特殊方法，构造实例的时候Python自动调用。
    def __init__(self, name, age):
        '''初始化属性。'''
        self.name = name
        self.__age = age
        
    def __str__(self):
        return 'Name: ' + self.name + ', Age: ' + str(self.__age)

    def get_name(self):
        return self.name
        
    def get_age(self):
        return self.__age

        
alice = Person('alice', 20)
print(alice)  # print会调用str(alice)，后者调用alice.__str__()
print(alice.name) # 'alice'
print(alice.__age) # AttributeError, check alice.__dict__

      
